use axum::extract::{Path, Query};
use axum::{Router, Json};
use axum::routing::{get, post};
use serde::{Serialize,Deserialize};
use tower_cookies::Cookies;

use crate::models::{User, Comment, CreateComment, Guide, CreateGuide, UpdateComment, UpdateGuide, CreateModRecommendation, ModRecommendation, UpdateModRecommendation};
use crate::utils::cookie;
use crate::utils::cookie::get_user_from_cookies;
type RouterResult<T> = Result<T,String>;


// struct RouterResponse {

// }

#[derive(Deserialize,Serialize)]
struct ModuleRecomResponse{
    pub discription:String,
    pub status:String,
    pub recom_id:String,
    pub comment_id:String,
}

impl ModuleRecomResponse{
    pub fn ok(discription:String,recom_id:String,comment_id:String) -> ModuleRecomResponse {
        ModuleRecomResponse { discription, status: "ok".to_string(), recom_id, comment_id}
    }

    pub fn err(discription:String,recom_id:String,comment_id:String) -> ModuleRecomResponse {
        ModuleRecomResponse { discription, status: "err".to_string(), recom_id, comment_id}
    }

}


pub fn router() -> Router {
    Router::new()
        .route("/", get(index))
        .route("/make_recom", post(make_recom))
        .route("/update_recom", post(update_recom))
        .route("/delete_recom", get(delete_recom))
        .route("/make_comment", post(make_comment))
        .route("/update_comment", post(update_comment))
        .route("/delete_comment", get(delete_comment))
        .route("/get_all",get(get_all))
}

async fn index(cookies:Cookies) -> RouterResult<String> {
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap();

    let user_id: i32 = user_id.parse().unwrap();

    let user = User::fetch_one_by_id(user_id).await.map_err(|err| err.to_string())?;

    Ok(format!("欢迎来到mod推荐特权首页，{}！",user.nickname))

}
/// 获取当前用户写的mod推荐
async fn get_all(cookies:Cookies) -> Json<Vec<ModRecommendation>> {
    let user_id = cookie::get_user_id_from_cookie(cookies).unwrap();
    let user_id:i32 = user_id.parse().unwrap();
    let m_rec = ModRecommendation::fetch_all_by_author_id(user_id).await.unwrap();
    // let m_rec = ModRecommendation::fetch_all().await.unwrap();


    Json(m_rec)

}

/// 添加mod推荐
async fn make_recom(Json(recom):Json<CreateModRecommendation>,cookies:Cookies) -> Json<ModuleRecomResponse> {
    let user_id:i32 = cookie::get_user_id_from_cookie(cookies).unwrap().parse().unwrap();

    let recom_id = ModRecommendation::insert(user_id, recom.content, recom.mod_type, recom.compatibility, recom.module_author, recom.module_origin, recom.image, vec![], "status".to_string()).await;

    if let Err(err) = recom_id {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    let recom_id = recom_id.unwrap();

    Json(ModuleRecomResponse::ok("成功创建了mod推荐".to_string(), recom_id.to_string(), "".to_string()))
}

/// 更新推荐
async fn update_recom(Json(recom):Json<UpdateModRecommendation>,cookies:Cookies) -> Json<ModuleRecomResponse> {
    // let user_id:i32 = cookie::get_user_id_from_cookie(cookies).unwrap().parse().unwrap();

    // let recom_id = ModRecommendation::insert(user_id, recom.content, recom.mod_type, recom.compatibility, recom.module_author, recom.module_origin, recom.image, vec![], "status".to_string()).await;

    let res = ModRecommendation::update_part_by_id(recom.id, recom.content, recom.mod_type, recom.compatibility, recom.module_author, recom.module_origin, recom.image).await;

    if let Err(err) = res {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    // let recom_id = recom_id.unwrap();

    Json(ModuleRecomResponse::ok("成功更新了mod推荐".to_string(), recom.id.to_string(), "".to_string()))
}

#[derive(Deserialize,Serialize)]
struct DeleteModRecom {
    recom_id:i32
}

/// 删除推荐
async fn delete_recom(Query(dr):Query<DeleteModRecom>) -> Json<ModuleRecomResponse> {
    let res = ModRecommendation::delete_by_id(dr.recom_id).await;
    if let Err(err) = res {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    Json(ModuleRecomResponse::ok("成功删除了mod推荐".to_string(), dr.recom_id.to_string(), "".to_string()))


}



/// 发表mod评论
async fn make_comment(Json(comment):Json<CreateComment>,cookies:Cookies) -> Json<ModuleRecomResponse> {
    let user_id:i32 = cookie::get_user_id_from_cookie(cookies).unwrap().parse().unwrap();
    
    let mod_recom = ModRecommendation::fetch_one_by_id(comment.of_id).await; //要评论的ModRecom
    if let Err(err) = mod_recom {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    let mut mod_recom = mod_recom.unwrap();


    // 建立一个comment
    let comment_id = Comment::insert(user_id, comment.content, comment.rate, "status".to_string()).await;

    if let Err(err) = comment_id {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    let comment_id = comment_id.unwrap();

    // let res = Guide::push_comment_by_id(guide_id, comment_id).await.map_err(|err| err.to_string());
    let res = mod_recom.push_comment(comment_id).await;
    if let Err(err) = res {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    Json(ModuleRecomResponse::ok("成功发表了mod评论".to_string(), mod_recom.id.to_string(), comment_id.to_string()))
}


#[derive(Serialize,Deserialize)]
struct DeleteComment {
    pub recom_id: i32,
    pub comment_id: i32
}

/// 删除mod评论
async fn delete_comment(Query(query):Query<DeleteComment>,cookies:Cookies) -> Json<ModuleRecomResponse> {
    let mod_recom = ModRecommendation::fetch_one_by_id(query.recom_id).await;

    
    if let Err(err) = mod_recom {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }
    let mut mod_recom = mod_recom.unwrap();

    let res = mod_recom.pop_comment(query.comment_id).await;
    if let Err(err) = res {
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    Json(ModuleRecomResponse::ok("成功删除了mod评论".to_string(), query.recom_id.to_string(), query.comment_id.to_string()))
}

/// 更新mod评论
async fn update_comment(Json(comment):Json<UpdateComment>,cookies:Cookies) -> Json<ModuleRecomResponse> {

    // 更新comment
    if let Err(err) = Comment::update_part_by_id(comment.id, comment.content, comment.rate).await{
        return Json(ModuleRecomResponse::err(err.to_string(), "".to_string(), "".to_string()));
    }

    Json(ModuleRecomResponse::ok("成功更新了mod评论".to_string(), "".to_string(), comment.id.to_string()))
}
